/*
 * SoftwareSAR - 1.0
 */
package br.com.cpqd.ssar.utilitarias;

/**
 * Representação de uma Geometria do Tipo STL
 * @author Rafael Buck
 * @version 1.1
 */
public class STL extends AtributosGeometria {

    /**
     * Lista de Triangulos que Representa o Formato do Objeto STL
     */
    private Triangulo[] listaTriangulos;
    /**
     * Caminho do Arquivo STL em Disco
     */
    private String caminhoArquivo;

    private int nElementos;

    /*
     * Coordenadas Maximas do STL em relacao ao dominio (celulas)
     */
     float[] maxReference = new float[3];
     
     /*
      * Coordenadas Minimas do STL em relacao ao dominio (celulas)
      * 
      */
     float[] minReference = new float[3];

    /**
     * Método Construtor
     */
    public STL() {
        super(null, 0);
    }

    /**
     * Método Construtor Sobrecarregado
     * @param listaTriangulos Triangulo[]
     * @param caminhoArquivo String
     */
    public STL(Triangulo[] listaTriangulos, String caminhoArquivo, int id, float[] reference1, float[] reference2, int tam) {
         super(reference1, id);
        this.listaTriangulos = listaTriangulos;
        this.caminhoArquivo = caminhoArquivo;
        minReference = reference1;
        maxReference = reference2;
        nElementos = tam;
    }

   /**
     * Get the value of listaTriangulos
     * @return the value of listaTriangulos
     */

    @Override
    public Triangulo[] getListaTriangulosSTL() {
        return listaTriangulos;
    }

    /**
     * Set the value of listaTriangulos
     * @param listaTriangulos new value of listaTriangulos
     */
    public void setListaTriangulos(Triangulo[] listaTriangulos) {
        this.listaTriangulos = listaTriangulos;
    }

    /**
     * Get the value of listaTriangulos at specified index
     * @param index
     * @return the value of listaTriangulos at specified index
     */
    public Triangulo getListaTriangulos(int index) {
        return this.listaTriangulos[index];
    }

    /**
     * Set the value of listaTriangulos at specified index.
     * @param index
     * @param newListaTriangulos new value of listaTriangulos at specified index
     */
    public void setListaTriangulos(int index, Triangulo newListaTriangulos) {
        this.listaTriangulos[index] = newListaTriangulos;
    }

    public void setNElements(int n) {
       nElementos = n;
    }


    @Override
    public int getNElements(){
        return nElementos;
    }

    @Override
    public void redimensionar() {
        throw new UnsupportedOperationException("Not supported yet.");
    }
        
    @Override
    public void redimensionarSTL(float[] min, float[] max) {

        int r = 0;
        float propx, propy, propz; // calcular a proporcao de ajuste (escala)
        float transx = 0, transy = 0, transz=0;

        Vertice[] vertices = new Vertice[3];  // Criacao de vertices de um elemento da malha
        float[] normal = new float[3];      // Criacao da normal de um elemento da malha

        if ((min[0]!= minReference[0])||(min[1]!=minReference[1])||(min[2]!=minReference[2])||
            (max[0]!= maxReference[0])||(max[1]!=maxReference[1])||(max[2]!=maxReference[2])){

            propx = (Math.abs(min[0])+Math.abs(max[0]))/(Math.abs(minReference[0])+Math.abs(maxReference[0]));
            propy = (Math.abs(min[1])+Math.abs(max[1]))/(Math.abs(minReference[1])+Math.abs(maxReference[1]));
            propz = (Math.abs(min[2])+Math.abs(max[2]))/(Math.abs(minReference[2])+Math.abs(maxReference[2]));

            System.out.println("PX:: " + propx + "  PROY:: " + propy + "  PROZ:: " + propz);
            for (int cont=0; cont < nElementos; cont++){

                vertices = listaTriangulos[cont].getVertice();
                normal   = listaTriangulos[cont].getNormal();

                // Procedimento para redimensionamento:
                // - Transladar a Geometria para a Origem
                // - Aplicar redimensionamento
                // - Transladar para a nova regiao de interesse

                // Primeiro Vertice
                vertices[0].setCoordenada(0, ((vertices[0].getCoordenada(0)-Math.abs(minReference[0]))*propx)+min[0]);
                vertices[0].setCoordenada(1, ((vertices[0].getCoordenada(1)-Math.abs(minReference[1]))*propy)+min[1]);
                vertices[0].setCoordenada(2, ((vertices[0].getCoordenada(2)-Math.abs(minReference[2]))*propz)+min[2]);

                // Segundo Vertice
                vertices[1].setCoordenada(0, ((vertices[1].getCoordenada(0)-Math.abs(minReference[0]))*propx)+min[0]);
                vertices[1].setCoordenada(1, ((vertices[1].getCoordenada(1)-Math.abs(minReference[1]))*propy)+min[1]);
                vertices[1].setCoordenada(2, ((vertices[1].getCoordenada(2)-Math.abs(minReference[2]))*propz)+min[2]);

                // Terceiro Vertice
                vertices[2].setCoordenada(0, ((vertices[2].getCoordenada(0)-Math.abs(minReference[0]))*propx)+min[0]);
                vertices[2].setCoordenada(1, ((vertices[2].getCoordenada(1)-Math.abs(minReference[1]))*propy)+min[1]);
                vertices[2].setCoordenada(2, ((vertices[2].getCoordenada(2)-Math.abs(minReference[2]))*propz)+min[2]);

                // NORMAL
                normal[0] = ((normal[0]-Math.abs(minReference[0]))*propx)+min[0];
                normal[1] = ((normal[1]-Math.abs(minReference[1]))*propx)+min[1];
                normal[2] = ((normal[2]-Math.abs(minReference[2]))*propx)+min[2];

                listaTriangulos[cont].setVertice(vertices);
                listaTriangulos[cont].setNormal(normal);
            }
        }
        minReference = min;
        maxReference = max;
    }


    @Override
    public float[] getFirsPoint() {
        return minReference;
    }

    @Override
    public float[] getSecondPoint() {
        return maxReference;
    }

    @Override
    public void setRaio(float radius) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public float getRaio() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public float getAltura() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void setAltura(float height) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void setSecondPoint(float[] secondPoint) {
        maxReference = secondPoint;
    }

    @Override
    public void setFirsPoint(float[] firstPoint) {
        minReference = firstPoint;
    }

    /**
     * Retorna a lista de Triangulos do proprio arquivo STL
     * @return Triangulo[] - listaTriangulos     * 
     */
    @Override
    public Triangulo[] triangularizarGeometria() {
        return listaTriangulos;
    }

    /**
     * Get the value of caminhoArquivo
     * @return the value of caminhoArquivo
     */
    @Override
    public String getCaminhoArquivo() {
        return caminhoArquivo;
    }

    /**
     * Set the value of caminhoArquivo
     * @param caminhoArquivo new value of caminhoArquivo
     */
    @Override
    public void setCaminhoArquivo(String caminhoArquivo) {
        this.caminhoArquivo = caminhoArquivo;
    }

    @Override
    public int getDiscretizacaoX() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void setDiscretizacaoX(int discretizacaoX) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public int getDiscretizacaoY() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void setDiscretizacaoY(int discretizacaoY) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public int getDiscretizacaoZ() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void setDiscretizacaoZ(int discretizacaoZ) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public double getDx() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public double getDy() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public double getDz() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public int getPmlXi() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void setPmlXi(int pmlXi) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public int getPmlXf() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void setPmlXf(int pmlXf) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public int getPmlYi() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void setPmlYi(int pmlYi) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public int getPmlYf() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void setPmlYf(int pmlYf) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public int getPmlZi() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void setPmlZi(int pmlZi) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public int getPmlZf() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void setPmlZf(int pmlZf) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public double getEscala() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void setEscala(double escala) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void setEscala(String tipo) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void addX() {
        for (int i = 0; i < listaTriangulos.length; i++) {
            for (int j = 0; j < 3; j++) {
                listaTriangulos[i].getVertice(j).setCoordenada(0, listaTriangulos[i].getVertice(j).getCoordenada(0) + 1);
            }
        }
    }

    @Override
    public void addX(float valor) {
        for (int i = 0; i < listaTriangulos.length; i++) {
            for (int j = 0; j < 3; j++) {
                listaTriangulos[i].getVertice(j).setCoordenada(0, listaTriangulos[i].getVertice(j).getCoordenada(0) + valor);
            }
        }
    }

    @Override
    public void addY() {
        for (int i = 0; i < listaTriangulos.length; i++) {
            for (int j = 0; j < 3; j++) {

                listaTriangulos[i].getVertice(j).setCoordenada(1, listaTriangulos[i].getVertice(j).getCoordenada(1) + 1);

            }
        }
    }

    @Override
    public void addY(float valor) {
        for (int i = 0; i < listaTriangulos.length; i++) {
            for (int j = 0; j < 3; j++) {

                listaTriangulos[i].getVertice(j).setCoordenada(1, listaTriangulos[i].getVertice(j).getCoordenada(1) + valor);

            }
        }
    }

    @Override
    public void addZ() {
        for (int i = 0; i < listaTriangulos.length; i++) {
            for (int j = 0; j < 3; j++) {

                listaTriangulos[i].getVertice(j).setCoordenada(2, listaTriangulos[i].getVertice(j).getCoordenada(2) + 1);

            }
        }
    }

    @Override
    public void addZ(float valor) {
        for (int i = 0; i < listaTriangulos.length; i++) {
            for (int j = 0; j < 3; j++) {

                listaTriangulos[i].getVertice(j).setCoordenada(2, listaTriangulos[i].getVertice(j).getCoordenada(2) + valor);

            }
        }
    }

    @Override
    public void subX() {
        for (int i = 0; i < listaTriangulos.length; i++) {
            for (int j = 0; j < 3; j++) {

                listaTriangulos[i].getVertice(j).setCoordenada(0, listaTriangulos[i].getVertice(j).getCoordenada(0) - 1);

            }
        }
    }

    @Override
    public void subY() {
        for (int i = 0; i < listaTriangulos.length; i++) {
            for (int j = 0; j < 3; j++) {

                listaTriangulos[i].getVertice(j).setCoordenada(1, listaTriangulos[i].getVertice(j).getCoordenada(1) - 1);

            }
        }
    }

    @Override
    public void subZ() {
        for (int i = 0; i < listaTriangulos.length; i++) {
            for (int j = 0; j < 3; j++) {

                listaTriangulos[i].getVertice(j).setCoordenada(2, listaTriangulos[i].getVertice(j).getCoordenada(2) - 1);

            }
        }
    }

    @Override
    public int getNSteps() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void subX(float valor) {
          for (int i = 0; i < listaTriangulos.length; i++) {
            for (int j = 0; j < 3; j++) {

                listaTriangulos[i].getVertice(j).setCoordenada(0, listaTriangulos[i].getVertice(j).getCoordenada(0) - valor);

            }
        }
    }

    @Override
    public void subY(float valor) {
          for (int i = 0; i < listaTriangulos.length; i++) {
            for (int j = 0; j < 3; j++) {

                listaTriangulos[i].getVertice(j).setCoordenada(1, listaTriangulos[i].getVertice(j).getCoordenada(1) - valor);

            }
        }
    }

    @Override
    public void subZ(float valor) {
        for (int i = 0; i < listaTriangulos.length; i++) {
            for (int j = 0; j < 3; j++) {

                listaTriangulos[i].getVertice(j).setCoordenada(2, listaTriangulos[i].getVertice(j).getCoordenada(2) - valor);

            }
        }
    }    
}
